import re
import json
import requests
from fastapi import APIRouter
from app.utils import make_response, ResponseCode
from app.common import logger, mongo_client, JSONEncoder
from app.schemas.lottery import Query, Phase
from settings import mongo_settings, openapi_settings


bp = APIRouter(prefix='/lottery')


def scrapy_lottery_by_phase(phase):
    """根据期数获取"""
    url = openapi_settings.api_phase_code.format(phase)
    headers = {'Referer': openapi_settings.api_refer}
    resp = requests.get(url, headers=headers, timeout=10)
    if resp.status_code != 200:
        raise requests.exceptions.HTTPError('请求依赖接口失败')
    resp_json = resp.json()
    if resp_json['state'] != 0:
        raise requests.exceptions.HTTPError('请求依赖接口返回数据异常')
    return resp_json['result']


def parse_lottery_from_rawdata(rawdata):
    """从原始数据中提取数据"""
    data = {
        '_id': rawdata['code'],
        'date': re.search(r'(\d{4}-\d{2}-\d{2})', rawdata['date']).group(),
        'blue': rawdata['blue'],
        'red': rawdata['red'].split(','),
        'poolmoney': rawdata['poolmoney'],
        'prizegrades': [
            {
                'grade': grade['type'],
                'number': grade['typenum'],
                'bonus': grade['typemoney']
            } for grade in rawdata['prizegrades']
        ]
    }
    return data


@make_response
def lotteries(body: Query):
    """开奖列表"""
    req_json = body.dict(by_alias=True)
    page = req_json['page']
    count = req_json['count']
    q = req_json['q']

    query = {}
    if q:
        if q['_id']:
            query['_id'] = {'$regex': q['_id']}
        if q['date']:
            query['date'] = {'$regex': q['date']}
    result = mongo_client.execute(
        mongo_client.client[mongo_settings.db_lottery][mongo_settings.col_lottery].find, query
    ).sort([('_id', -1)]).skip((page - 1) * count).limit(count)
    total = result.count()
    data = json.loads(JSONEncoder().encode(list(result)))
    resp_data = {
        'page': page,
        'count': count,
        'total': total,
        'data': data
    }
    return ResponseCode.Success.value, '', resp_data


@make_response
def lottery(_id: str):
    """开奖期数详情"""
    query = {'_id': _id}
    result = mongo_client.execute(
        mongo_client.client[mongo_settings.db_lottery][mongo_settings.col_lottery].find_one, query
    )
    if result:
        return ResponseCode.Success.value, '', json.loads(JSONEncoder().encode(result))
    return ResponseCode.Success.value, '', {}


@make_response
def latest():
    """最新开奖"""
    query = {}

    result = mongo_client.execute(
        mongo_client.client[mongo_settings.db_lottery][mongo_settings.col_lottery].find,
        query
    ).sort([('_id', -1)]).limit(1)

    data = json.loads(JSONEncoder().encode(list(result)))[0]
    return ResponseCode.Success.value, '', data


@make_response
def scrapy(body: Phase):
    """爬取指定期数数据"""
    req_json = body.dict(by_alias=True)
    _id = req_json['_id']

    query = {'_id': _id}
    item = mongo_client.execute(
        mongo_client.client[mongo_settings.db_lottery][mongo_settings.col_lottery].find_one,
        query,
        {'_id': 1}
    )
    if item:
        return ResponseCode.Success.value, '数据已经存在', {}
    results = scrapy_lottery_by_phase(_id)
    datas = list(map(parse_lottery_from_rawdata, results))
    mongo_client.execute(
        mongo_client.client[mongo_settings.db_lottery][mongo_settings.col_lottery].insert,
        datas[0]
    )
    return ResponseCode.Success.value, '数据爬取成功', {}


bp.add_api_route(path='/list', name='lotteries', endpoint=lotteries, methods=['POST'], tags=['开奖记录'])
bp.add_api_route(path='/item', name='lottery', endpoint=lottery, methods=['GET'], tags=['开奖记录'])
bp.add_api_route(path='/latest', name='latest', endpoint=latest, methods=['GET'], tags=['开奖记录'])
bp.add_api_route(path='/scrapy', name='scrapy', endpoint=scrapy, methods=['POST'], tags=['数据爬取'])
